﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;

using ERPStore.Extensions;
using ERPStore.NewsLetters.Repositories;

using System.Data.Entity.Validation;

namespace ERPStore.NewsLetters.Services
{
	public class TrackerService
	{
		public TrackerService(CloudSoft.Repositories.IRepository<NewsLettersDbContext> repository
			, ERPStore.Logging.ILogger logger)
		{
			this.Repository = repository;
			this.Logger = logger;
		}

		protected CloudSoft.Repositories.IRepository<NewsLettersDbContext> Repository { get; private set; }
		protected ERPStore.Logging.ILogger Logger { get; private set; }

		public IList<Models.Track> GetLastOpenedEmail(int campaignId, int count)
		{
			var list = from data in Repository.Query<Repositories.Datas.TrackData>()
					   where data.CampaingId == campaignId
					   orderby data.Id descending
					   select data;

			var top = list.Take(count).ToList();
			var result = AutoMapper.Mapper.Map<IList<Models.Track>>(top);
			return result;
		}

		public int GetTrackCount(int campaignId)
		{
			var result = Repository.Query<Repositories.Datas.TrackData>()
							.Where(i => i.CampaingId == campaignId)
							.Count();

			return result;
		}

		public void WriteTrack(Models.TrackingKey tracking, DateTime creationDate, string rawurl, string ip, string destinationUrl, int? emailSentId)
		{
			var track = new Repositories.Datas.TrackData();
			track.CreationDate = creationDate;
			track.EventDate = DateTime.Now;
			track.CampaingId = tracking.CampaignId;
			track.Email = tracking.Email;
			track.LinkName = tracking.LinkName;
			track.NewsLetterId = tracking.NewsLetterId;
			track.UserId = tracking.UserId;
			track.Ip = ip;
			track.Url = rawurl;
			track.EmailSentId = emailSentId;
			track.DestinationUrl = destinationUrl;

			try
			{
				Repository.Insert<Repositories.Datas.TrackData>(track);
			}
			catch (DbEntityValidationException ex)
			{
				int i = 0;
				foreach (var validationErrors in ex.EntityValidationErrors)
				{
					foreach (var validationError in validationErrors.ValidationErrors)
					{
						ex.Data.Add(string.Format("SqlTrackRepository.Write.{0}", i), string.Format("{0}:{1}", validationError.PropertyName, validationError.ErrorMessage));
						i++;
					}
				}
				Logger.Error(ex);
			}
			catch (Exception ex)
			{
				Logger.Error(ex);
			}
		}

		public Models.CampaignStat GetCampaignStatById(int id)
		{
			var stat = Repository.Get<Repositories.Datas.CampaignStatData>(i => i.CampaignStatId == id);
			return AutoMapper.Mapper.Map<Models.CampaignStat>(stat);
		}

		public IList<Models.CampaignStat> GetCampaignStatListByIdList(IEnumerable<int> idList)
		{
			var list = Repository.Query<Repositories.Datas.CampaignStatData>().Where(i => idList.Contains(i.CampaignStatId));
			return AutoMapper.Mapper.Map<IList<Models.CampaignStat>>(list);
		}

		public Dictionary<string, int> GetCampaignClickStatByLink(int campaignId)
		{
			var query = from track in Repository.Query<Repositories.Datas.TrackData>()
						where track.CampaingId == campaignId
						group track by new { track.CampaingId, track.LinkName } into g
						select new
						{
							LinkName = g.Key.LinkName,
							Count = g.Count()
						};

			return query.ToDictionary(k => k.LinkName, v => v.Count);
		}
	}
}
